package connectfour;


import java.io.IOException;
import java.io.PrintWriter;
import java.util.Date;
import javax.jdo.PersistenceManager;
import javax.jdo.Query;
import javax.jdo.Transaction;
import javax.servlet.http.*;

import com.google.appengine.api.labs.taskqueue.Queue;
import com.google.appengine.api.labs.taskqueue.QueueFactory;
import com.google.appengine.api.labs.taskqueue.TaskOptions;
import com.google.appengine.api.memcache.MemcacheService;
import com.google.appengine.api.memcache.MemcacheServiceFactory;
import com.google.appengine.api.users.User;
import com.google.appengine.api.users.UserService;
import com.google.appengine.api.users.UserServiceFactory;
import com.google.appengine.api.datastore.DatastoreService;
import com.google.appengine.api.datastore.DatastoreServiceFactory;
import com.google.appengine.api.datastore.Entity;
import com.google.appengine.api.datastore.EntityNotFoundException;
import com.google.appengine.api.datastore.KeyFactory;


@SuppressWarnings("serial")
public class PlacePieceServlet extends HttpServlet{
	public void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException {
		PersistenceManager pm = PMF.get().getPersistenceManager();
		//MemcacheService mc = MemcacheServiceFactory.getMemcacheService();

		Game game = null;
		
		/*
		// get game entity corresponding to this game
		if(mc.contains("game" + req.getParameter("gameID"))){
			game = (Game) mc.get("game" + req.getParameter("gameID"));
		}
		else{
			try {
				game = pm.getObjectById(Game.class, KeyFactory.createKey("Game", 
						Long.parseLong(req.getParameter("gameID"))));
	
			} finally {
			}
		}
		*/
		
		try {
			game = pm.getObjectById(Game.class, KeyFactory.createKey("Game", 
					Long.parseLong(req.getParameter("gameID"))));

		} finally {
		}
		
		// place the new piece in the appropriate column and increment the turn counter
		game.setGrid(Integer.parseInt(req.getParameter("col")), 
				Integer.parseInt(req.getParameter("pID")));
		game.incTurn();
		
		// check to see if this move makes this player the winner		
		boolean endGame = game.hasWon(Integer.parseInt(req.getParameter("pID")));
		
		
		Player p1 = null;
		Player p2 = null;
			
		if(endGame){
			/*
			// update player stats if the game has been won
			if(mc.contains("player" + game.getUserHost().getUserId())){
				p1 = (Player) mc.get("player" + game.getUserHost().getUserId());
			}
			else{
				p1 = pm.getObjectById(Player.class, game.getHost());
			}
			*/
			
			p1 = pm.getObjectById(Player.class, game.getHost());
			/*
			if(mc.contains("player" + game.getUserOpponent().getUserId())){
				p2 = (Player) mc.get("player" + game.getUserOpponent().getUserId());
			}
			else{
				p2 = pm.getObjectById(Player.class, game.getOpponent());
			}
			*/
			p2 = pm.getObjectById(Player.class, game.getOpponent());
			/*
			if(Integer.parseInt(req.getParameter("pID")) == 1){ // p1 has won
				p1.incWins();
				p2.incLosses();
				p1.setRatio();
				p2.setRatio();
			}
			else{  // p2 has won
				p1.incLosses();
				p2.incWins();
				p1.setRatio();
				p2.setRatio();
			}
			*/
			
			game.setWinner(Integer.parseInt(req.getParameter("pID")));
			game.isOver(true);
			
			// invalidate the leaderboard in the memcache because it may be stale
			/*
			if(mc.contains("TopFive")){
				mc.delete("TopFive");
			}
			*/
		}

		
		Transaction tx = pm.currentTransaction();
		Queue q = QueueFactory.getDefaultQueue();
		TaskOptions t = null;
		
		//p1.getStatus();
		//p2.getStatus();
		
		try{
			tx.begin();
			
			pm.makePersistent(game);
			//pm.makePersistent(p1);
			//pm.makePersistent(p2);

			if(endGame){
				if(Integer.parseInt(req.getParameter("pID")) == 1){ // p1 has won
					t = TaskOptions.Builder.url("/persist").param("pKey", 
							KeyFactory.keyToString(p1.getKey())).param("status", "4").param("wins", "1")
							.param("losses", "0").param("ratio", "1");
					q.add(t);
					t = TaskOptions.Builder.url("/persist").param("pKey", 
							KeyFactory.keyToString(p2.getKey())).param("status", "4").param("wins", "0")
							.param("losses", "1").param("ratio", "1");
					q.add(t);
				}
				else{  // p2 has won
					t = TaskOptions.Builder.url("/persist").param("pKey", 
							KeyFactory.keyToString(p1.getKey())).param("status", "4").param("wins", "0")
							.param("losses", "1").param("ratio", "1");
					q.add(t);
					t = TaskOptions.Builder.url("/persist").param("pKey", 
							KeyFactory.keyToString(p2.getKey())).param("status", "4").param("wins", "1")
							.param("losses", "0").param("ratio", "1");
					q.add(t);
				}
			}
			
			tx.commit();

		}finally{
			if(tx.isActive()){
				tx.rollback();
			}

			pm.close();
		}	
		
		// update the memcache
		//mc.put("game" + game.getKey().getId(), game);
		
		/*
		if(endGame){
			mc.put("player" + p1.getPlayer().getUserId(), p1);
			mc.put("player" + p2.getPlayer().getUserId(), p2);
		}
		*/
		
		resp.sendRedirect("/game.jsp?gameID=" + game.getKey().getId());
	}
	
	public void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
		
		PersistenceManager pm = PMF.get().getPersistenceManager();
		MemcacheService mc = MemcacheServiceFactory.getMemcacheService();
		
		Game game = null;
		
		if(mc.contains("game" + req.getParameter("gameID"))){
			game = (Game) mc.get("game" + req.getParameter("gameID"));
		}
		else{
			game = pm.getObjectById(Game.class, KeyFactory.createKey("Game", 
				Long.parseLong(req.getParameter("gameID"))));
		}
		
		
		int turn = Integer.parseInt(req.getParameter("turn"));
		
		String response = "";
		
		if(game.isOver()){
			response += "over ";
		}
		else if(game.getTurn() > turn) {
			response += "change ";
		}
		else {
			response += "same";
		}
		
		if(game.isOver() || game.getTurn() > turn){
			int x = game.getLastMove() % 8;
			int y = (game.getLastMove() - x) / 8;
			
			String c;
			if(game.getValue(x,y) == 1) c = "black";
			else if(game.getValue(x,y) == 2) c = "red";
			else c = "empty";
			
			 response += x + " " + y + " " + c + " " + game.getTurn();
			 
			 if(game.isOver()){
				 response += " " + game.getWinner();
			 }
		}
		
		resp.setContentType("text/plain");
		resp.getWriter().write(response);
	}
}

